#! python3
# 使用 imapclient 模块从 IMAP 服务器下载电子邮件。
# 使用 pyzmail 模块解析邮件
import os

import imapclient
import imaplib
import pyzmail
import pprint
import re


def receiveEmail():
    try:
        # 1、连接到 IMAP 服务器:
        imapObj = imapclient.IMAPClient('imap.qq.com', ssl=True)
        # print(imapObj)

        #  2、登录到 IMAP 服务器
        imapObj.login('xxxx@qq.com', 'xxxx')

        #  3、获取文件夹列表、选择一个文件夹进行
        # imapObj.list_folders()
        # pprint.pprint(imapObj.list_folders())
        imapObj.select_folder('Deleted Messages', readonly=True)  # 搜索草稿箱文件夹

        #  4、执行搜索, 详见：表 16-3 IMAP 搜索键，需要再研究测试
        #  返回邮件的唯一Uid
        # UIDs = imapObj.search(['ON 16-Jul-2020'])  # 搜索文件夹中 2020 年 7 月 16 日的每个消息
        UIDs = imapObj.search(['ALL'])  # 搜索文件夹中来自某个地址的邮件
        # print(UIDs)

        # 删除邮件需要将第3个步骤中的readonly设置为False)
        # imapObj.delete_messages(UIDs)  # 标记为已删除
        # imapObj.expunge()  # 永久删除

        #  5、将限制从默认的 10000 字节改为 10000000 字节
        imaplib._MAXLINE = 10000000

        #  6、取邮件并标记为已读(需要将第3个步骤中的readonly设置为False)
        rawMessages = imapObj.fetch(UIDs, ['BODY[]'])
        # imapObj.set_flags(rawMessages, b'\\Seen', silent=False)
        # pprint.pprint(rawMessages)

        #  7、从消息中读取电子邮件信息
        for uid in UIDs:
            message = pyzmail.PyzMessage.factory(rawMessages[uid][b'BODY[]'])
            print("======================" * 10)
            print("======================" * 10)
            print('邮件主题：' + message.get_subject(),
                  '发件地址：' + str(message.get_addresses('from')),
                  '收件地址：' + str(message.get_addresses('to')),
                  '抄送地址：' + str(message.get_addresses('cc')),
                  '密送地址：' + str(message.get_addresses('bcc')),
                  '密送地址：' + str(message.get_filename()),
                  sep="\n")

            #  获取正文
            #  如果电子邮件是纯文本，它的 PyzMessage 对象会将 html_part 属性设为 None
            #  如果电子邮件是 HTML ，它的 PyzMessage对象会将 text_part 属性设为 None
            if message.text_part is None:  # 邮件是HTML
                # print('邮件是HTML:', message.html_part)
                content = message.html_part.get_payload().decode(message.html_part.charset)
                fileName = "%s.html" % message.get_subject()
            else:
                # print('邮件是纯文本:', message.text_part)
                content = message.text_part.get_payload().decode(message.text_part.charset)
                fileName = "%s.txt" % message.get_subject()
            print('邮件正文：', content, '\n')
            #  保存邮件正文
            fileName = fileName.replace('\\', '').replace('/', '') \
                .replace(':', "").replace('?', "").replace('"', '')\
                .replace('>', '').replace('<', '').replace('|', '')
            fEx = open(os.path.join('email', fileName), 'w', encoding='utf-8')
            fEx.write(content)
            fEx.close()

            # 提取邮件内容里面的链接
            pattern = re.compile(r'\b(([\w-]+://?|www[.])[^\s()<>]+(?:[\w\d]+|([^[:punct:]\s]|/)))')
            # ms = re.search(pattern, content)
            ms = pattern.findall(content)
            # print('m', ms)
            if len(ms) > 0:
                print('正文中的链接：')
                for i in range(len(ms)):
                    url = ms[i][0]
                    print(url)

            #  附件下载：可以下载附件，但是读取附件名称有问题
            # for part in message.walk():
            #     fileName = part.get_filename()
            #     name = part.get_param('name')
            #     print(fileName, name, sep='\n')
            #     #  保存附件
            #     if fileName:
            #         data = part.get_payload(decode=True)
            #         fileName = "%s.docx" % (message.get_subject())
            #         fEx = open(fileName, 'wb')
            #         fEx.write(data)
            #         fEx.close()

            print()

        # 8、 从 IMAP 服务器断开
        imapObj.logout()

    except Exception as exc:
        print("程序异常了：" + exc)


if __name__ == '__main__':
    receiveEmail()
